"""
  端口镜像-审计
"""
import copy

import openstack
from flask import current_app
from flask_restx import abort, reqparse

from app.api.v1.organizer.rangeEnv import RangeBase
from app.models import taasModel
from utils.crypto import decrypt_pw
from utils.utils import init_openstack


class TaasService(RangeBase):
    def __init__(self, api=None, *args, **kwargs):
        super().__init__(api=api, *args, **kwargs)
        self.conn = init_openstack(self.user.project_id, current_app.config)

    def create_tap_service(self, port_id, range_uuid):
        try:
            tap_service = self.conn.create_tap_service(port_id)
            tap_service_id = tap_service["tap_service"]["id"]
            obj = taasModel.TapService(
                tap_service=tap_service_id, port_id=port_id, range_uuid=range_uuid
            )
            taasModel.db.session.add(obj)
            taasModel.db.session.commit()
        except Exception as e:
            current_app.logger.exception(e)
            abort(500, message="创建审计失败")
        return True

    def delete_tap_service(self, port_id):
        tap_s = taasModel.TapService.query.filter_by(port_id=port_id).first()
        self.conn.delete_tap_service(tap_s.tap_service)
        vm_port = taasModel.VmPortName.query.filter_by(port_id=port_id).first()
        taasModel.db.session.delete(tap_s)
        taasModel.db.session.delete(vm_port)
        taasModel.db.session.commit()


class TaasFlow(TaasService):
    def __init__(self, api=None, *args, **kwargs):
        super().__init__(api=api, *args, **kwargs)
        openstackAuthConfig = decrypt_pw(current_app.config["OPENSTACK"]["auth"])
        config = copy.copy(openstackAuthConfig)
        config["username"] = "admin"
        config["password"] = "adminadmin.123123"
        config["project_id"] = "ecc33e26d5f6463e8b071999aebd7f1f"
        self.admin_conn = openstack.connect(
            auth=config, auth_type=current_app.config["OPENSTACK"]["auth_type"]
        )

    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("range_uuid", help="靶场信息有误", required=True)
        parser.add_argument("tap_service", help="审计虚拟机", required=True)
        parser.add_argument("source_port_list", help="被监控虚拟机列表", required=True)
        args = parser.parse_args()
        try:
            for source_port in args["source_port_list"].split(","):
                port_info = self.admin_conn.get_port(source_port)
                host = port_info["binding:host_id"]

                flow = self.conn.create_tap_flow(source_port, args["tap_service"])[
                    "tap_flow"
                ]
                obj = taasModel.TapFlow(
                    tap_service=args["tap_service"],
                    flow_id=flow["id"],
                    source_port_id=source_port,
                    host=host,
                    range_uuid=args["range_uuid"],
                )
                taasModel.db.session.add(obj)
                taasModel.db.session.commit()
        except Exception as e:
            current_app.logger.exception(e)
            abort(500, message="创建失败")
        return {"code": 200, "info": "创建成功"}

    def delete(self):
        parser = reqparse.RequestParser()
        parser.add_argument("source_port_list", help="被监控虚拟机列表", required=True)
        args = parser.parse_args()
        for source_port in args["source_port_list"].split(","):
            flow = taasModel.TapFlow.query.filter_by(source_port_id=source_port).first()
            if flow:
                self.conn.delete_flow(flow.flow_id)
                taasModel.db.session.delete(flow)
                taasModel.db.session.commit()
                return {"code": 200, "info": "删除成功"}
            else:
                vm_port = taasModel.VmPortName.query.filter_by(
                    port_id=source_port
                ).first()
                abort(500, message="%s 没有被监控流量" % vm_port.vm_name)

    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument("range_uuid", help="靶场信息有误", required=True)
        parser.add_argument("vm_uuid", help="审计虚拟机id", required=True)
        args = parser.parse_args()
        range_vms = taasModel.VmPortName.query.filter_by(
            range_uuid=args["range_uuid"]
        ).all()
        vm_name_list = []
        for vm in range_vms:
            if vm.vm_uuid != args["vm_uuid"]:
                vm_name_list.append(vm.vm_name)
        flows = taasModel.TapFlow.query.filter_by(range_uuid=args["range_uuid"]).all()
        flow_vm_name_list = []
        for flow in flows:
            vm_name_port = taasModel.VmPortName.query.filter_by(
                port_id=flow.source_port_id
            ).first()
            flow_vm_name_list.append(vm_name_port.vm_name)
        no_flow_vm = list(set(vm_name_list) - set(flow_vm_name_list))
        date = {"flow_vm": flow_vm_name_list, "no_flow_vm": no_flow_vm}
        return {"code": 200, "data": date}
